#!/usr/bin/env python
# encoding: utf-8
#
# Copyright (c) 2010 Richard F. Burghause.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
wavehandler.py

Handles Wave API calls
"""
from waveapi import appengine_robot_runner
from waveapi import robot
from waveapi import events
from google.appengine.ext import db
from google.appengine.api import users
from django.utils import simplejson

import logging
import datetime
import model

class WaveStreamRobot(robot.Robot):
	"""	The WaveStreamRobot class represents our robot in the Google Wave.
		This class holds meta information of our robot and implements
		required event handlers.
	"""
	
	def OnWaveletSelfAdded(self, event, wavelet):
		"""
		Invoked when the robot has been added.
		This is similar to the creation of a new Wavelet.
		Here we create our first revision of that particular Wavelet.
		Thereby we give the participants a short note, that this wave can
		now be subscribed. 
		Internally a new Wave is created or updated in the data store
		"""
		logging.info("Robot has been added to %s (%s) in Wave %s" % (repr(wavelet.title), repr(wavelet.wavelet_id), repr(wavelet.wave_id), ) )
		wave = model.Wave.get_or_insert(key_name=wavelet.wave_id,waveID=wavelet.wave_id)
		waveletData = model.Wavelet(parent=wave,
									waveletID=wavelet.wavelet_id,
									creator=users.User(wavelet.creator),
									#creationTime=datetime.fromtimestamp(wavelet.creation_time),
									domain=wavelet.domain,
									#lastModifiedTime=datetime.fromtimestamp(wavelet.last_modified_time),
									title=wavelet.title,
									dataDocuments=simplejson.dumps(wavelet.data_documents.serialize()),
									participants=[users.User(identifier) for identifier in wavelet.participants],
									tags=simplejson.dumps(wavelet.tags.serialize()))
		waveletData.put()
		logging.info(repr(wavelet.blips))
		for blip in [wavelet.blips.get(blipID) for blipID in wavelet.blips]:
			waveletData.blips.append( model.constructBlip(waveletData, blip).put() )
#		if wavelet.root_blip:
#			waveleData.rootBlip = blips[wavelet.root_blip.blip_id]
		waveletData.put()
		wavelet.reply("\nHi everybody. This is the wave-stream robot. The following wave can now be subscribed under ...")

	def OnWaveletSelfRemoved(self, event, wavelet):
		"""
		Invoked when the robot has been removed.
		We will no longer be subscribed to this particular Wavelet.
		Therefore internally the current Wavelet is removed from the data store.
		"""
		logging.info("Robot has been removed from %s (%s) in Wave %s" % (repr(wavelet.title), repr(wavelet.wavelet_id), repr(wavelet.wave_id), ) )
		waveletData = db.Query(model.Wavelet).filter('waveletID =', wavelet.wavelet_id).get()
		if waveletData:
			for child in db.Query(model.Wavelet).ancestors(waveletData).fetch():
				child.delete()
			waveletData.delete()
		#wavelet.reply('\nThis wave has been unsubscribed and is no longer available as a feed.')

	def OnWaveletParticipantsChanged(self, event, wavelet):
		"""
		Invoked when the participants have changed
		"""
		#logging.info("OnWaveletParticipantsChanged called")
	
	def OnWaveletBlipCreated(self, event, wavelet):
		"""
		Invoked when a new blip has been created
		"""
		#logging.info("OnWaveletBlipCreated called")
		
	def OnWaveletBlipRemoved(self, event, wavelet):
		"""
		Invoked when a blip has been removed
		"""
		#logging.info("OnWaveletBlipRemoved called")
	
	def OnBlipSubmitted(self, event, wavelet):
		"""
		Invoked whenever a blip has been submitted
		"""
		#logging.info("OnBlipRemoved called")
	
	def OnBlipContributorsChanged(self, event, wavelet):
		"""
		Invoked whenever the contributors to a blip
		have been changed
		"""
		#logging.info("OnBlipContributorsChanged called")
	
	def OnDocumentChanged(self, event, wavelet):
		"""
		Invoked whenever the document has changed
		Causion: May result in an increased traffic
		"""
		#logging.info("OnDocumentChanged")
		#logging.info(repr(event))
		#logging.info(repr(wavelet))
	
	def __init__(self):
		super(WaveStreamRobot, self).__init__('wave-stream',
						image_url='http://wave-stream.appspot.com/r/icon.png',
						profile_url='https://wave-stream.appspot.com/r/about-wave-stream-robot.html')
		self.register_handler(events.WaveletSelfAdded, self.OnWaveletSelfAdded)
		self.register_handler(events.WaveletSelfRemoved, self.OnWaveletSelfRemoved)
		#self.register_handler(events.WaveletParticipantsChanged, self.OnWaveletParticipantsChanged)
		#self.register_handler(events.WaveletBlipCreated, self.OnWaveletBlipCreated)
		#self.register_handler(events.WaveletBlipRemoved, self.OnWaveletBlipRemoved)
		#self.register_handler(events.BlipSubmitted, self.OnBlipSubmitted)
		#self.register_handler(events.BlipContributorsChanged, self.OnBlipContributorsChanged)
		#self.register_handler(events.DocumentChanged, self.OnDocumentChanged)

if __name__ == '__main__':
	waveStreamRobot = WaveStreamRobot()
	appengine_robot_runner.run(waveStreamRobot)
